home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvitovdu32
/
src
/
pascal
/
screenio.p
< prev
next >
Wrap
Text File
|
1991-11-10
|
8KB
|
280 lines
(* ScreenIO implements terminal i/o routines used by DVItoVDU.
Highly SYSDEP!
*)
#include 'globals.h';
#include 'screenio.h';
#include 'unixio.h';
#include 'vdu.h';
(* IMPORT InitVDU, StartText, ClearScreen, ResetVDU.
To handle ^Z suspension properly, ScreenIO needs to use some VDU routines.
*)
(* SYSDEP: We need to use the following Unix io routines.
In particular, using Pascal's write/writeln has some nasty side-effect
that prevents BusyRead from working!
*)
FUNCTION getchar : integer; EXTERNAL;
FUNCTION putchar (ch : char) : integer; EXTERNAL;
FUNCTION write(f : integer; VAR b : screenbuf; n : integer) : integer; EXTERNAL;
(******************************************************************************)
PROCEDURE WriteChar (ch : CHAR);
(* This is the only place where a character is put into the output buffer.*)
VAR dummy : integer;
BEGIN
IF buflen = maxbufsize THEN BEGIN
dummy := write(1,buf,buflen); (* write entire buffer *)
buflen := 0;
END;
buf[buflen] := ch;
buflen := buflen + 1;
END; (* WriteChar *)
(******************************************************************************)
PROCEDURE WriteBuffer;
(* Output the buffer; either buffer is full or client has explicitly
requested the terminal to be updated.
*)
VAR dummy : integer;
BEGIN
IF buflen > 0 THEN BEGIN
dummy := write(1,buf,buflen);
buflen := 0;
END;
END; (* WriteBuffer *)
(******************************************************************************)
PROCEDURE WriteLine;
BEGIN
WriteChar(CR);
WriteBuffer; (* WriteLine also updates terminal *)
END; (* WriteLine *)
(******************************************************************************)
PROCEDURE WriteString (s: string);
(* This routine will not display trailing blanks. *)
LABEL 888;
VAR i, j : integer;
BEGIN
j := maxstring;
WHILE j > 0 DO BEGIN
j := j - 1;
IF s[j] <> ' ' THEN goto 888;
END;
888:
FOR i := 0 TO j DO WriteChar(s[i]);
END; (* WriteString *)
(******************************************************************************)
PROCEDURE WriteCard (c : INTEGER);
(* Since the vast majority of given values will be small numbers, we avoid
recursion until c >= 100.
*)
BEGIN
IF c < 10 THEN
WriteChar( CHR(ORD('0') + c) )
ELSE IF c < 100 THEN BEGIN
WriteChar( CHR(ORD('0') + (c DIV 10)) );
WriteChar( CHR(ORD('0') + (c MOD 10)) );
END
ELSE BEGIN
WriteCard(c DIV 100); (* recursive if c >= 100 *)
c := c MOD 100;
WriteChar( CHR(ORD('0') + (c DIV 10)) );
WriteChar( CHR(ORD('0') + (c MOD 10)) );
END;
END; (* WriteCard *)
(******************************************************************************)
PROCEDURE WriteInt (i : INTEGER);
BEGIN
IF i < 0 THEN BEGIN
WriteChar('-');
i := ABS(i);
END;
WriteCard(i);
END; (* WriteInt *)
(******************************************************************************)
PROCEDURE RestoreTerminal;
(* RestoreTerminal should be called before any client module terminates. *)
BEGIN
WriteBuffer; (* make sure terminal is up-to-date *)
restoretty; (* restore terminal characteristics saved below *)
END; (* RestoreTerminal *)
(******************************************************************************)
PROCEDURE ReadChar (VAR ch : CHAR);
VAR dummy : integer;
BEGIN
(* assume singlecharon has been called *)
ch := CHR(getchar);
(* check for CTRLC or CTRLZ *)
IF ch = CTRLC THEN BEGIN (* interrupt *)
ch := CHR(getchar); (* remove terminator *)
ch := CR; (* return to Command: level *)
END
ELSE IF ch = CTRLZ THEN BEGIN (* suspend *)
ch := CHR(getchar); (* remove terminator *)
StartText; ClearScreen; WriteLine; ResetVDU;
RestoreTerminal;
suspend;
savetty; singlecharon; echooff;
InitVDU; StartText;
ClearScreen;
ch := CR; (* return to Command: level *)
END
ELSE
dummy := putchar(ch); (* echo ch since echooff has been called *)
END; (* ReadChar *)
(******************************************************************************)
PROCEDURE ReadString (VAR s : string);
(* Read a string of characters.
The routine is terminated upon carriage return.
*)
LABEL 888;
VAR ch : CHAR; i : INTEGER;
BEGIN
singlecharoff; (* read string in cooked mode *)
echoon; (* echo characters *)
s := ' '; (* init s with spaces *)
i := 0;
WHILE TRUE DO BEGIN
ch := CHR(getchar);
IF ch = CR THEN goto 888;
s[i] := ch;
IF i = maxstring THEN goto 888;
IF ch = CTRLC THEN BEGIN (* interrupt *)
s := ' ';
goto 888;
END
ELSE IF ch = CTRLZ THEN BEGIN (* suspend *)
StartText; ClearScreen; WriteLine; ResetVDU;
RestoreTerminal;
suspend;
savetty;
(* singlecharon and echooff are called below *)
InitVDU; StartText;
ClearScreen;
s := ' ';
goto 888;
END;
i := i + 1;
END;
888:
singlecharon; (* return to cbreak mode *)
echooff; (* and no echo *)
END; (* ReadString *)
(******************************************************************************)
FUNCTION BusyRead (VAR ch : CHAR) : BOOLEAN;
(* Return TRUE if ch is waiting in input buffer, and read it with no echo.
If nothing in input buffer then ch is undefined and we return FALSE.
*)
BEGIN
(* SYSDEP: buffercount assumes singlecharon and echooff have been called *)
IF buffercount = 0 THEN
BusyRead := FALSE
ELSE BEGIN
ch := CHR(getchar);
IF ch = CTRLC THEN BEGIN (* interrupt *)
ch := CHR(getchar); (* read terminator *)
ch := CR; (* main module will return to Command: level *)
END
ELSE IF ch = CTRLZ THEN BEGIN
(* suspend *)
ch := CHR(getchar); (* read terminator *)
StartText; ClearScreen; WriteLine; ResetVDU;
RestoreTerminal;
suspend;
savetty; singlecharon; echooff;
InitVDU; StartText;
ClearScreen;
ch := CR; (* after suspend, return to Command: level *)
END;
BusyRead := TRUE;
END;
END; (* BusyRead *)
(******************************************************************************)
PROCEDURE InitTeXtoASCII;
(* Initialize TeXtoASCII array used in specific ShowChar/Rectangle routines
to map a given TeX char into a similar, displayable ASCII char.
*)
VAR ch : CHAR;
BEGIN
FOR ch := CHR( 0b) TO CHR( 12b) DO TeXtoASCII[ch] := '?'; (* Greek letters *)
FOR ch := CHR(13b) TO CHR( 17b) DO TeXtoASCII[ch] := '?'; (* ligatures *)
TeXtoASCII[CHR(20b)] := 'i'; (* dotless i *)
TeXtoASCII[CHR(21b)] := 'j'; (* dotless j *)
TeXtoASCII[CHR(22b)] := '`'; (* grave accent *)
TeXtoASCII[CHR(23b)] := ''''; (* acute accent *)
FOR ch := CHR(24b) TO CHR( 27b) DO TeXtoASCII[ch] := '~'; (* high accents *)
TeXtoASCII[CHR(30b)] := ','; (* cedilla *)
FOR ch := CHR(31b) TO CHR( 40b) DO TeXtoASCII[ch] := '?'; (* foreigns *)
FOR ch := CHR(41b) TO CHR(133b) DO TeXtoASCII[ch] := ch ; (* same *)
TeXtoASCII[CHR(134b)] := '"'; (* open dble quote *)
TeXtoASCII[CHR(135b)] := ']'; (* same *)
FOR ch := CHR(136b) TO CHR(137b) DO TeXtoASCII[ch] := '^'; (* more accents *)
FOR ch := CHR(140b) TO CHR(172b) DO TeXtoASCII[ch] := ch ; (* same *)
FOR ch := CHR(173b) TO CHR(174b) DO TeXtoASCII[ch] := '-'; (* en & em dash *)
FOR ch := CHR(175b) TO CHR(177b) DO TeXtoASCII[ch] := '~'; (* more accents *)
FOR ch := CHR(200b) TO CHR(377b) DO TeXtoASCII[ch] := '?';
END; (* InitTeXtoASCII *)
(******************************************************************************)
PROCEDURE InitScreenIO;
BEGIN
InitTeXtoASCII;
buflen := 0;
(* We first save the current terminal characteristics.
savetty also sets up ^C/^Z interrupt handlers; see unixio.c.
*)
savetty;
singlecharon; (* cbreak mode for ReadChar and BusyRead *)
echooff; (* no echo for BusyRead *)
END; (* InitScreenIO *)